Skip to content

Scan Management API

This document is based on the following source files:

  • internal/handlers/scan.go -- Scan handler (scan actions + business settings endpoints)
  • internal/app/routers.go -- Route registration
  • internal/services/scan_progress.go -- Scan progress model
  • internal/services/fingerprint.go -- Fingerprint computation service

Table of Contents

  1. Overview
  2. Scan Operation Endpoints
  3. Fingerprint Computation Endpoints
  4. Scan Business Settings Endpoints

1. Overview

The scan management module handles the discovery, importing, and directory management of local music files. All endpoints require JWT authentication (BearerAuth), with the base path /api/v1.

ScanHandler carries both the scan action endpoints and the scan-related business settings endpoints (/settings/*), consolidating the business-oriented reads/writes of config keys such as music_path and scan_playlist_mode into a single handler.


2. Scan Operation Endpoints

2.1 POST /scan -- Scan and Import Local Music

Method: POSTPath: /api/v1/scanAuthentication: BearerAuth required

Description: Asynchronously scans the music directory and imports newly discovered music files into the database. Returns immediately; status can be polled via /scan/progress.

Request body:

json
{
  "reimport": false
}
FieldTypeRequiredDescription
reimportbooleanNoWhether to re-import files that already exist (default false)

Success response (200):

json
{
  "message": "扫描任务已启动"
}

Error responses:

StatusDescription
409A scan is already in progress
500Failed to start scan

2.2 GET /scan/progress -- Get Scan Progress

Method: GETPath: /api/v1/scan/progressAuthentication: BearerAuth required

Description: Gets progress information for the current scan task.

Success response (200):

json
{
  "status": "scanning",
  "total_files": 1000,
  "scanned_files": 500,
  "imported_files": 480,
  "skipped_files": 15,
  "failed_files": 5,
  "cleaned_files": 0,
  "current_file": "/music/album/track.mp3",
  "start_time": "2026-06-12T10:00:00Z",
  "end_time": null,
  "error": ""
}
FieldTypeDescription
statusstringCurrent status: idle / scanning / importing / creating_playlists / completed / failed / cancelling / cancelled
total_filesintTotal number of files
scanned_filesintNumber of scanned files
imported_filesintNumber of imported files
skipped_filesintNumber of skipped files (already exist)
failed_filesintNumber of failed files
cleaned_filesintNumber of stale files cleaned up
current_filestringPath of the file currently being processed
start_timestring/nullStart time (ISO 8601)
end_timestring/nullEnd time (ISO 8601)
errorstringError message

2.3 POST /scan/cancel -- Cancel Scan

Method: POSTPath: /api/v1/scan/cancelAuthentication: BearerAuth required

Description: Cancels the scan task in progress.

Success response (200):

json
{
  "message": "扫描任务已取消"
}

Error responses:

StatusDescription
400No scan task is in progress

2.4 GET /scan/directories -- Get Subdirectory List

Method: GETPath: /api/v1/scan/directoriesAuthentication: BearerAuth required

Description: Returns the list of first-level subdirectories under the specified path, used for lazy loading of the directory tree. When path is empty, returns the subdirectories under the music root directory.

Query parameters:

ParameterTypeRequiredDescription
pathstringNoDirectory path (uses the music root directory when empty)

Success response (200):

json
{
  "directories": ["/music/pop", "/music/rock"],
  "root": "/music"
}

Error responses:

StatusDescription
400The path must be under the music directory (prevents directory traversal attacks)
500Failed to read directory

2.5 GET /scan/dir-names -- Get All Directory Names

Method: GETPath: /api/v1/scan/dir-namesAuthentication: BearerAuth required

Description: Recursively collects all unique directory names under the music directory, returned in alphabetical order, used for autocompletion of excluded directory names.

Success response (200):

json
{
  "names": ["@eaDir", "Classical", "Pop", "Rock", "tmp"]
}

Error responses:

StatusDescription
500Failed to collect directory names

3. Fingerprint Computation Endpoints

3.1 GET /scan/fingerprints/status -- Get Fingerprint Computation Status

Method: GETPath: /api/v1/scan/fingerprints/statusAuthentication: BearerAuth required

Description: Returns ffmpeg chromaprint availability and local song fingerprint computation statistics.

Success response (200):

json
{
  "chromaprint_available": true,
  "total": 1000,
  "computed": 800,
  "missing": 200
}
FieldTypeDescription
chromaprint_availablebooleanWhether ffmpeg chromaprint is available
totalintTotal number of local songs
computedintNumber of songs with computed fingerprints
missingintNumber of songs missing fingerprints

3.2 POST /scan/fingerprints -- Trigger Batch Fingerprint Computation

Method: POSTPath: /api/v1/scan/fingerprintsAuthentication: BearerAuth required

Description: Asynchronously computes audio fingerprints for local songs; requires ffmpeg with chromaprint support. If a task is already running, it is interrupted and restarted.

Request body:

json
{
  "recompute_all": false
}
FieldTypeRequiredDescription
recompute_allbooleanNoWhen true, clears existing fingerprints and recomputes all (default false, computes only the missing ones)

Success response (200):

json
{
  "status": "started",
  "total": 200
}

Error responses:

StatusDescription
400ffmpeg chromaprint is unavailable

3.3 GET /scan/fingerprints/progress -- Get Fingerprint Computation Progress

Method: GETPath: /api/v1/scan/fingerprints/progressAuthentication: BearerAuth required

Description: Queries the progress of the current fingerprint computation task.

Success response (200):

json
{
  "status": "running",
  "computed": 150,
  "total": 200,
  "failed": 3
}
FieldTypeDescription
statusstringTask status: idle / running / done
computedintNumber computed
totalintTotal number of tasks
failedintNumber failed

4. Scan Business Settings Endpoints

The following endpoints are business-oriented configuration interfaces that provide strongly-typed JSON, come with built-in defaults, and trigger side effects inline after PUT. They write to the same config row as the generic /configs/{key} interface, but frontend business features should always go through these endpoints.

4.1 GET/PUT /settings/music-path -- Music Path Configuration

Path: /api/v1/settings/music-pathAuthentication: BearerAuth required

GET -- Get music path and scan exclusion configuration

Success response (200):

json
{
  "path": "music",
  "exclude_dirs": ["@eaDir", "tmp"],
  "exclude_paths": []
}
FieldTypeDescription
pathstringMusic directory path (default "music")
exclude_dirsstring[]List of excluded directory names
exclude_pathsstring[]List of excluded specific paths

PUT -- Update music path and scan exclusion configuration

After writing the configuration, asynchronously triggers a Scanner rebuild + cleanup of songs in excluded directories (the side effect is consistent with the admin /configs/music_path PUT).

Request body: Same format as the GET response. path cannot be empty.

Error responses:

StatusDescription
400Bad request format or empty path
500Failed to save configuration

4.2 GET/PUT /settings/scan-playlist-mode -- Playlist Merge Mode

Path: /api/v1/settings/scan-playlist-modeAuthentication: BearerAuth required

Controls the directory merge mode when automatically creating playlists after a scan. Default directory.

GET response / PUT request body:

json
{
  "mode": "directory"
}
FieldTypeAllowed valuesDescription
modestringdirectory / top_level / bubble_updirectory: generate an independent playlist for each folder (default); top_level: merge playlists by first-level subdirectory; bubble_up: songs appear simultaneously in the playlists of all parent folders

PUT error responses:

StatusDescription
400Bad request format or illegal mode value (only the three enum values above are accepted)
500Failed to save configuration

4.3 GET/PUT /settings/scan-auto-create-playlists -- Auto-Create Playlists Switch

Path: /api/v1/settings/scan-auto-create-playlistsAuthentication: BearerAuth required

Controls whether playlists are automatically created based on the music directory structure after a scan completes. Enabled by default (true). When disabled, scanning only imports songs into the database and no longer auto-creates playlists.

GET response / PUT request body:

json
{
  "enabled": true
}

4.4 GET/PUT /settings/scan-title-source -- Scan Title Source Configuration

Path: /api/v1/settings/scan-title-sourceAuthentication: BearerAuth required

Configures the source of the song title during scanning. After switching, a scan in "re-import" mode is required for it to take effect. Triggers a Scanner rebuild after PUT completes.

GET response / PUT request body:

json
{
  "title_source": "tag"
}
FieldTypeAllowed valuesDescription
title_sourcestringtag / filenametag: prefer the title in the audio tags (default); filename: always use the file name (without extension)

PUT error responses:

StatusDescription
400Bad request format or invalid title_source value
500Failed to save configuration

4.5 GET/PUT /settings/auto-scan -- Auto Scan Configuration

Path: /api/v1/settings/auto-scanAuthentication: BearerAuth required

Configures the enabled state and scan interval of auto scan. Takes effect immediately after an update (no restart required), asynchronously triggering the auto-scan scheduler to reconfigure.

GET response / PUT request body:

json
{
  "enabled": false,
  "interval_seconds": 3600
}
FieldTypeDescription
enabledbooleanWhether to enable auto scan (default false)
interval_secondsintScan interval in seconds (default 3600, valid range 60-86400)

PUT error responses:

StatusDescription
400Bad request format or interval_seconds not in the range 60-86400
500Failed to save configuration

Section source: internal/handlers/scan.go / internal/app/routers.go / internal/services/scan_progress.go / internal/services/fingerprint.go